Memory leaks and stability fixes in KML realtime writer.
authorrobertl <robertl>
Sun, 5 Nov 2006 22:48:41 +0000 (22:48 +0000)
committerrobertl <robertl>
Sun, 5 Nov 2006 22:48:41 +0000 (22:48 +0000)
Allow position reader (Garmin, NMEA) to propogate error up to caller.

defs.h
garmin.c
kml.c
main.c
nmea.c
reference/earth-expertgps.kml
reference/earth-gc.kml

diff --git a/defs.h b/defs.h
index 4236e79aac92c672b5f5a0748343ac9b4454366c..3c2d5ad9337d0b41ed224f28a2b0cfa68dd0d0fa 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -399,13 +399,17 @@ typedef struct {
        double min_lon;
 } bounds;
 
+typedef struct {
+       int request_terminate;
+} posn_status;
+
 typedef void (*ff_init) (char const *);
 typedef void (*ff_deinit) (void);
 typedef void (*ff_read) (void);
 typedef void (*ff_write) (void);
 typedef void (*ff_exit) (void);
 typedef void (*ff_writeposn) (waypoint *);
-typedef waypoint * (*ff_readposn) (void);
+typedef waypoint * (*ff_readposn) (posn_status *);
 
 #ifndef DEBUG_MEM
 char * get_option(const char *iarglist, const char *argname);
index 3f74b8088210e1e96fdec5fc56a0bbdf3d304aac..c696357b07823fc54fa4fb8b91e67ec4fc2163e9 100644 (file)
--- a/garmin.c
+++ b/garmin.c
@@ -469,7 +469,7 @@ pvt_init(const char *fname)
 }
 
 static waypoint *
-pvt_read(void)
+pvt_read(posn_status *posn_status)
 {
        waypoint *wpt = waypt_new();
        GPS_PPvt_Data pvt = GPS_Pvt_New();
@@ -477,10 +477,18 @@ pvt_read(void)
        if (GPS_Command_Pvt_Get(&pvt_fd, &pvt)) {
                pvt2wpt(pvt, wpt);
                wpt->shortname = xstrdup("Position");
+
+               if (gps_errno && posn_status) {
+                       posn_status->request_terminate = 1;
+               }
        
                return wpt;
        } 
 
+       /*
+        * If the caller has not given us a better way to return the
+        * error, do it now. 
+        */
        if (gps_errno) {
                fatal(MYNAME ": Fatal error reading position.\n");
        }
@@ -825,7 +833,7 @@ ff_vecs_t garmin_vecs = {
        NULL,
        garmin_args,
        CET_CHARSET_ASCII, 0,
-       { pvt_init, pvt_read, NULL, NULL, NULL, NULL }
+       { pvt_init, pvt_read, rw_deinit, NULL, NULL, NULL }
 };
 
 static const char *d103_icons[16] = {
diff --git a/kml.c b/kml.c
index a6aef26281f13292380085361ac044a62f0fa565..aad6876789902801eb9da831136fda7ba9aa2551 100644 (file)
--- a/kml.c
+++ b/kml.c
@@ -40,7 +40,6 @@ static int export_points;
 static int floating;
 static int extrude;
 static int trackdata;
-static int posn_track_points;
 static int max_position_points;
 
 static int indent_level;
@@ -807,7 +806,7 @@ void kml_write(void)
 
        kml_write_xml(0,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
        kml_write_xml(1,"<kml xmlns=\"http://earth.google.com/kml/2.1\">\n");
-       kml_write_xml(1,"<Document xmlns:xlink=\"http://www.w3/org/1999/xlink\">\n");
+       kml_write_xml(1,"<Document xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n");
 
        now = current_time();
        strftime(import_time, sizeof(import_time), "%c", localtime(&now));
@@ -882,12 +881,17 @@ kml_get_posn_icon(int freshness)
 }
 
 
+static route_head *posn_trk_head = NULL;
+
 static void
 kml_wr_position(waypoint *wpt)
 {
-       static route_head *trk_head = NULL;
        static time_t last_valid_fix;
-       waypoint *t = waypt_dupe(wpt);
+
+       if (!posn_trk_head) {
+               posn_trk_head = route_head_alloc();
+               track_add_head(posn_trk_head);
+       }
 
        if (last_valid_fix == 0) last_valid_fix = current_time();
 
@@ -913,25 +917,23 @@ kml_wr_position(waypoint *wpt)
                        last_valid_fix = wpt->creation_time;
        }
 
-
        wpt->icon_descr = kml_get_posn_icon(wpt->creation_time - last_valid_fix);
-       if (!trk_head) {
-               trk_head = route_head_alloc();
-               track_add_head(trk_head);
-       }
 
-       if (max_position_points && (posn_track_points >= max_position_points)) {
-               waypoint *tonuke = (waypoint *) QUEUE_FIRST(&trk_head->waypoint_list);
-               dequeue(&tonuke->Q);
-               waypt_free(tonuke);
-       }
-
-       track_add_wpt(trk_head, t);
-       posn_track_points++;
+       track_add_wpt(posn_trk_head, waypt_dupe(wpt));
 
        waypt_add(wpt);
        kml_write();
        waypt_del(wpt);
+
+       /*
+        * If we are keeping only a recent subset of the trail, trim the
+        * head here.
+        */
+       while (max_position_points && 
+              (posn_trk_head->rte_waypt_ct >= max_position_points)) {
+               waypoint *tonuke = (waypoint *) QUEUE_FIRST(&posn_trk_head->waypoint_list);
+               track_del_wpt(posn_trk_head, tonuke);
+       }
 }
 
 ff_vecs_t kml_vecs = {
diff --git a/main.c b/main.c
index d06c0862c0b216cf2f1820b721dea4c3eb81d1ed..06e49d1611671c65e4e6f6fe1d3643d47c5637f4 100644 (file)
--- a/main.c
+++ b/main.c
@@ -541,7 +541,6 @@ main(int argc, char *argv[])
         * in our most recent vecs.
         */
        if (global_opts.masked_objective & POSNDATAMASK) {
-               waypoint *wpt = waypt_new();
 
                if (!ivecs->position_ops.rd_position) {
                        fatal("Realtime tracking (-T) is not suppored by this input type.\n");
@@ -565,7 +564,15 @@ main(int argc, char *argv[])
                }
 
                while (1) {
-                       wpt = ivecs->position_ops.rd_position();
+                       posn_status status;
+                       status.request_terminate = 0;
+                       waypoint *wpt = ivecs->position_ops.rd_position(&status);
+                       if (status.request_terminate) {
+                               if (wpt) {
+                                       waypt_free(wpt);
+                               }
+                               break;
+                       }
                        if (wpt) {
                                if (ovecs) {
                                        ovecs->position_ops.wr_init(ofname);
@@ -575,11 +582,17 @@ main(int argc, char *argv[])
                                        /* Just print to screen */
                                        waypt_disp(wpt);
                                }
+                               waypt_free(wpt);
                        }
                }
-//             waypt_del(wpt);
+               if (ivecs->position_ops.rd_deinit) {
+                       ivecs->position_ops.rd_deinit();
+               }
+               if (ivecs->position_ops.wr_deinit) {
+                       ivecs->position_ops.wr_deinit();
+               }
        }
-       
+
 
        if (!did_something)
                fatal ("Nothing to do!  Use '%s -h' for command-line options.\n", prog_name);
diff --git a/nmea.c b/nmea.c
index b078ba39ba95b8848ddb4052b89d9f0a0333878f..7d946e57adec4b184452a38705ddd69994c50d19 100644 (file)
--- a/nmea.c
+++ b/nmea.c
@@ -179,7 +179,7 @@ static int getposn;
 static time_t last_time = -1;
 static double last_read_time;   /* Last timestamp of GGA or PRMC */
 
-static waypoint * nmea_rd_posn(void);
+static waypoint * nmea_rd_posn(posn_status *);
 static void nmea_rd_posn_init(const char *fname);
 
 arglist_t nmea_args[] = {
@@ -226,8 +226,9 @@ nmea_rd_init(const char *fname)
         */
        if (getposn) {
                waypoint *wpt;
+               posn_status st;
                nmea_rd_posn_init(fname);
-               wpt = nmea_rd_posn();
+               wpt = nmea_rd_posn(&st);
                if (!wpt) {
                        return;
                }
@@ -817,7 +818,7 @@ nmea_rd_posn_init(const char *fname)
                read_mode = rm_serial;
                gbser_set_speed(gbser_handle, 4800);
        } else {
-               fatal(MYNAME ": Could not open %s.\n", fname);
+               fatal(MYNAME ": Could not open '%s' for position tracking.\n", fname);
        }
 
        if (opt_baud) {
@@ -829,7 +830,7 @@ nmea_rd_posn_init(const char *fname)
 }
 
 static waypoint *
-nmea_rd_posn(void)
+nmea_rd_posn(posn_status *posn_status)
 {
        char ibuf[1024];
        static double lt = -1;
index c434cb89c865fbf5ae0d7dcb1c4f5699bb530f72..3d97dacac8b38d5f9a600a89ea198a6796f26b03 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <kml xmlns="http://earth.google.com/kml/2.1">
-  <Document xmlns:xlink="http://www.w3/org/1999/xlink">
+  <Document xmlns:xlink="http://www.w3.org/1999/xlink">
     <name>GPS device</name>
 <!-- Normal route style -->
     <Style id="route_n">
index 9f08e18ceb4aa2afd06e4d562271973ce48d25c1..87c3b9c96f060bd33f058138cd72463caaa6ab9d 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <kml xmlns="http://earth.google.com/kml/2.1">
-  <Document xmlns:xlink="http://www.w3/org/1999/xlink">
+  <Document xmlns:xlink="http://www.w3.org/1999/xlink">
     <name>GPS device</name>
 <!-- Normal route style -->
     <Style id="route_n">